package dbtask

import (
	"reflect"
	"github.com/astaxie/beego/orm"
	"fmt"
	"cloud_worm/util/umodels/mysqldb"
)

type WeaponTask struct {
	Id                  int64
	TaskId              string                  // 任务id值
	TaskOwner           string                  // 创建任务的人
	TargetType          int                     // 目标类型：1：应用名、2: 主机ip地址
	Target              string                  // 目标值
	WeaponsName         string                  // 涉及的weapon的名字
	Comment             string                  // 描述信息

	SumCount            int                     // 涉及执行动作的总条数
	OkCount             int                     // ok的总条数
	FailedCount         int                     // 失败的条数
	PassCount           int                     // 通过的条数
	AlertCount          int                     // 执行结果是告警alert的条数

	Created             int64                   // 创建时间
	Updated             int64                   // 更新时间
	Status              int                     // 任务的状态：0：未执行；1：执行中；2：成功执行完成；3：执行失败；4: 存在alert
}

func (w *WeaponTask) TableName() string {
	return reflect.TypeOf(*w).Name()
}

func (w *WeaponTask) Read(fields ...string) error {
	err := orm.NewOrm().Read(w, fields...)
	if err != nil {
		return fmt.Errorf("%s, %s", w.TableName(), err.Error())
	}
	return nil
}

func (w *WeaponTask) Update(fields ...string) error {
	_, err := orm.NewOrm().Update(w, fields...)
	if err != nil {
		return fmt.Errorf("%s, %s", w.TableName(), err.Error())
	}
	return nil
}

func (w *WeaponTask) Insert() error {
	_, err := orm.NewOrm().Insert(w)
	if err != nil {
		return fmt.Errorf("%s, %s", w.TableName(), err.Error())
	}

	return nil
}

func init()  {
	orm.RegisterModel(new(WeaponTask))
}

func (w *WeaponTask) Select(offset int, limit int, status int, taskOwner string, taskId string) ([]*WeaponTask, error) {
	var tasks []*WeaponTask

	qs := orm.NewOrm().QueryTable(w).Offset(offset).Limit(limit)

	if status != mysqldb.StatusAll {
		qs = qs.Filter("status", status)
	}
	if taskId != mysqldb.SelectStrAll {
		qs = qs.Filter("task_id__istartswith", taskId)
	}
	if taskOwner != mysqldb.SelectStrAll {
		qs = qs.Filter("task_owner__istartswith", taskOwner)
	}

	_, err := qs.All(&tasks)
	if err != nil {
		return nil, err
	}

	return tasks, nil
}

func (w *WeaponTask) SelectOrderByUpdate(offset int, limit int, status int, taskOwner string, taskId string) ([]*WeaponTask, error) {
	var tasks []*WeaponTask

	qs := orm.NewOrm().QueryTable(w).Offset(offset).Limit(limit).OrderBy("-updated")

	if status != mysqldb.StatusAll {
		qs = qs.Filter("status", status)
	}
	if taskId != mysqldb.SelectStrAll {
		qs = qs.Filter("task_id__istartswith", taskId)
	}
	if taskOwner != mysqldb.SelectStrAll {
		qs = qs.Filter("task_owner__istartswith", taskOwner)
	}

	_, err := qs.All(&tasks)
	if err != nil {
		return nil, err
	}

	return tasks, nil
}

func (w *WeaponTask) SelectCount(status int, taskOwner string, taskId string) (int64, error) {

	qs := orm.NewOrm().QueryTable(w)
	if status != mysqldb.StatusAll {
		qs = qs.Filter("status", status)
	}
	if taskId != mysqldb.SelectStrAll {
		qs = qs.Filter("task_id__istartswith", taskId)
	}
	if taskOwner != mysqldb.SelectStrAll {
		qs = qs.Filter("task_owner__istartswith", taskOwner)
	}

	count, err := qs.Count()
	if err != nil {
		return 0, err
	}

	return count, nil
}

func (w *WeaponTask) CountByTimeDuration(startTime int64, endTime int64) (int64, error) {
	if startTime >= endTime {
		return 0, fmt.Errorf("input start_time(%d) and end_time(%d) error", startTime, endTime)
	}

	qs := orm.NewOrm().QueryTable(w)
	qs = qs.Filter("created__gt", startTime).Filter("created__lte", endTime)

	count, err := qs.Count()
	if err != nil {
		return 0, err
	}
	return count, nil
}

func (w *WeaponTask) SelectByTimeDuration(startTime int64, endTime int64) ([]*WeaponTask, error) {
	if startTime >= endTime {
		return nil, fmt.Errorf("input start_time(%d) and end_time(%d) error", startTime, endTime)
	}

	var tasks []*WeaponTask
	qs := orm.NewOrm().QueryTable(w).Offset(mysqldb.SelectOffsetZero).Limit(mysqldb.SelectLimitAll)
	qs = qs.Filter("created__gt", startTime).Filter("created__lte", endTime)

	_, err := qs.All(&tasks)
	if err != nil {
		return nil, err
	}

	return tasks, nil
}

func (w *WeaponTask) CheckCountByTimeDuration(startTime int64, endTime int64) (int64, error) {
	tasks, err := w.SelectByTimeDuration(startTime, endTime)
	if err != nil {
		return 0, err
	}

	cnt := 0
	for _, item := range tasks {
		cnt = cnt + item.SumCount
	}

	return int64(cnt), nil
}

